home *** CD-ROM | disk | FTP | other *** search
/ Revista CD Expert 8 / Revista CD Expert nº 08 CD1.iso / Utilitarios / Programacao / Pacific C for DOS / INCLUDE / XMS.H < prev   
C/C++ Source or Header  |  1995-03-08  |  16KB  |  449 lines

  1. /*
  2.  *    $Header: /home1/colin/xms/RCS/xms.h,v 1.15 94/08/12 11:31:24 colin Exp $
  3.  *
  4.  *    HI-TECH/Pacific C XMS Routines
  5.  *
  6.  *    Written by Colin Weaver, July 1994
  7.  *    Copyright (C) 1994, HI-TECH Software
  8.  *    All Rights Reserved
  9.  *
  10.  *    This software remains the property of HI-TECH SOFTWARE and is
  11.  *    supplied under licence only. The use of this software is
  12.  *    permitted under the terms of that licence only. Copying of
  13.  *    this software except for the purpose of making backup or
  14.  *    working copies for the use of the licensee on a single
  15.  *    processor is prohibited.
  16.  *
  17.  *    $Log:    xms.h,v $
  18.  * Revision 1.15  94/08/12  11:31:24  colin
  19.  * Added XVOIDPTR type, changed XMEMALLOC, XMEMFREE, XMEMGET and XMEMPUT
  20.  * to use "glue" functions instead of in-line code generation.
  21.  * 
  22.  * Revision 1.14  94/08/12  10:23:46  colin
  23.  * Added XNULL macro for XMEMPTR null test.
  24.  * 
  25.  * Revision 1.13  94/08/11  16:11:36  colin
  26.  * Added XMEMPUT and XMEMGET macros for transparent XMEMPTR read/write
  27.  * 
  28.  * Revision 1.12  94/08/11  10:26:32  colin
  29.  * Added XMEMALLOC and XMEMFREE macros for allocation and de-allocation
  30.  * of pointers declared using the XMEMPTR macro.
  31.  * 
  32.  * Revision 1.11  94/08/10  16:58:42  colin
  33.  * Added XMEMPTR macro for parameterised declaration of types and
  34.  * variables which are a union of an XMS pointer and a conventional
  35.  * memory pointer.
  36.  * 
  37.  * Revision 1.10  94/08/05  10:21:11  colin
  38.  * Upgraded _xms_sbrk(), _xms_malloc(), etc., to use 32 bit block sizes.
  39.  * 
  40.  * Revision 1.9  94/08/03  14:11:30  colin
  41.  * In order to avoid name confusion, renamed low level routines as follows:
  42.  *   _xms_free()       -->    _xms_dispose()
  43.  *   _xms_realloc()       -->    _xms_resize()
  44.  *   _xms_realloc_bytes()  -->    _xms_resize_bytes()
  45.  *   _xms_calloc()       -->    _xms_calloc()
  46.  * Added "high level" XMS routines, equivalent to the <stdlib.h> routines:
  47.  * _xms_sbrk(), _xms_malloc(), _xms_free(), _xms_realloc(), _xms_calloc(),
  48.  * _xms_put() and _xms_get().  New type _XMS_POINTER which is used to encode
  49.  * an XMS handle/offset pair, used by the new XMS routines.
  50.  * 
  51.  * Revision 1.8  94/08/01  16:55:18  colin
  52.  * Added _xms_memmove() function (XMS to XMS block copy)
  53.  * 
  54.  * Revision 1.7  94/07/29  16:53:22  colin
  55.  * New routines _xms_calloc() and _xms_memset().
  56.  * 
  57.  * Revision 1.6  94/07/26  13:00:49  colin
  58.  * Added prototypes for "high level" XMS routines: _xms_flush(),
  59.  * _xms_write() and _xms_read().
  60.  * 
  61.  * Revision 1.5  94/07/22  16:52:30  colin
  62.  * Changed _xms_realloc() and _xms_realloc_bytes() to return an _XMS_HANDLE.
  63.  * 
  64.  * Revision 1.4  94/07/21  12:06:13  colin
  65.  * Added "used" field to _XMS_FREE structure.
  66.  * 
  67.  * Revision 1.3  94/07/20  14:37:39  colin
  68.  * Added prototypes for byte count oriented allocation routines
  69.  * _xms_alloc_bytes() and _xms_realloc_bytes().
  70.  * 
  71.  * Revision 1.2  94/07/19  16:04:12  colin
  72.  * Changed struct _XMS_VERSION to split revision number into
  73.  * major and minor revisions.  Renamed version number fields.
  74.  * 
  75.  * Revision 1.1  94/07/19  12:52:49  colin
  76.  * Initial revision
  77.  * 
  78.  */
  79.  
  80. #if    !defined(_XMS_H_)
  81. #define    _XMS_H_    1
  82.  
  83. #include    <stdlib.h>
  84. #include    <string.h>
  85.  
  86. /*
  87.  *    typedef _XMS_HANDLE:    XMS Block Handle
  88.  *    typedef _XMS_SIZE_T:    XMS Block Size Type
  89.  */
  90.  
  91. typedef unsigned int    _XMS_HANDLE;
  92. typedef unsigned int    _XMS_SIZE_T;
  93.  
  94. /*
  95.  *    struct _XMS_VERSION:    XMS Version Information
  96.  */
  97.  
  98. struct _XMS_VERSION {
  99.     unsigned char    ver_major;    /* Major version number */
  100.     unsigned char    ver_minor;    /* Minor version number */
  101.     unsigned char    rev_major;    /* Major revision number */
  102.     unsigned char    rev_minor;    /* Minor revision number */
  103.     unsigned int    hma_exists;    /* HMA existence flag */
  104. };
  105.  
  106. /*
  107.  *    struct _XMS_FREE:    XMS Free Memory
  108.  */
  109.  
  110. struct _XMS_FREE {
  111.     _XMS_SIZE_T    maxblock;    /* largest free block (Kb) */
  112.     _XMS_SIZE_T    total;        /* total free XMS (Kb) */
  113.     _XMS_SIZE_T    used;        /* XMS used */
  114. };
  115.  
  116. /*
  117.  *    struct _XMS_MOVE:    XMS Move Parameter Block
  118.  *
  119.  *    The XMS Move Parameter Block is used to control moves between
  120.  *    extended and conventional memory.  The _XMS_MOVE block can also
  121.  *    control moves entirely within extended or conventional memory.
  122.  *
  123.  *    The fields within an _XMS_MOVE block are used as follows:
  124.  *
  125.  *    "count"        number of bytes to transfer
  126.  *
  127.  *    "src_handle"    XMS handle of transfer source, or 0 if the
  128.  *            source is in conventional memory.
  129.  *    "src.ptr"    only if "src_handle == 0", pointer to source
  130.  *            block in conventional memory
  131.  *    "src.offset"    only if "src_handle != 0", offset of source
  132.  *            within the XMS block described by "src_handle".
  133.  *
  134.  *    "dst_handle"    XMS handle of transfer destination, or 0 if the
  135.  *            destination is in conventional memory.
  136.  *    "dst.ptr"    only if "dst_handle == 0", pointer to destination
  137.  *            block in conventional memory
  138.  *    "dst.offset"    only if "dst_handle != 0", offset of destination
  139.  *            within the XMS block described by "dst_handle".
  140.  *
  141.  *    E.g. to store a string to XMS:
  142.  *
  143.  *    struct _XMS_MOVE    move;
  144.  *    _XMS_HANDLE        handle;
  145.  *    char            string[256];
  146.  *
  147.  *    strcpy(string, "TEST DATA!\n");
  148.  *    move.count = sizeof(string);
  149.  *    move.src_handle = 0;
  150.  *    move.src.ptr = string;
  151.  *    move.dst_handle = handle;
  152.  *    move.dst.offset = 0;
  153.  *    if (!_xms_move(&move))
  154.  *        printf("XMS MOVE FAILED!\n");
  155.  */
  156.  
  157. union _ptr_ofs {
  158.     far void *    ptr;
  159.     unsigned long    offset;
  160. };
  161.  
  162. struct _XMS_MOVE {
  163.     unsigned long    count;        /* transfer byte count */
  164.     _XMS_HANDLE    src_handle;    /* source XMS handle */
  165.     union _ptr_ofs    src;        /* source offset or address */
  166.     _XMS_HANDLE    dst_handle;    /* destination XMS handle */
  167.     union _ptr_ofs    dst;        /* destination offset or address */
  168. };
  169.  
  170. /*
  171.  *    struct _XMS_INFO:    EMB Handle Information
  172.  */
  173.  
  174. struct _XMS_INFO {
  175.     unsigned char    lock_count;    /* lock count of block */
  176.     unsigned char    free_handles;    /* number of free handles */
  177. };
  178.  
  179. /*
  180.  *    typedef _XMS_DRIVER:    Pointer to XMS Driver
  181.  */
  182.  
  183. typedef    far void *    _XMS_DRIVER;
  184.  
  185. /*
  186.  *    _xms_errno:    XMS error flag.
  187.  */
  188.  
  189. extern unsigned char    _xms_errno;        /* error number from last call */
  190. extern unsigned char    _xms_driver_realloc;    /* use driver realloc call only */
  191.  
  192. /*
  193.  *    _xms_error codes.  The codes below are the list of XMS error
  194.  *    codes as documented for XMS 2.0.  Not all of these codes may
  195.  *    be returned by the C functions implemented.  It is possible
  196.  *    that newer XMS implementations may return codes which are not
  197.  *    defined in this list.
  198.  *
  199.  *    First code group is for HI-TECH/Pacific C specific:
  200.  */
  201.  
  202. #define    XM_NO_CACHE    0xFC    /* XMS cache couldn't be created */
  203. #define    XM_MOVE_FAILED    0xFD    /* MOVE in realloc failed */
  204. #define    XM_BAD_ARG    0xFE    /* BAD argument to library function */
  205. #define    XM_NO_INIT    0xFF    /* XMS routines not initialized */
  206.  
  207. /*
  208.  *    The codes below are standard XMS codes
  209.  */
  210.  
  211. #define    XM_NO_ERROR    0x00    /* no XMS error */
  212. #define    XM_NO_FUNC    0x80    /* function not implemented */
  213. #define    XM_VDISK    0x81    /* VDISK device detected */
  214. #define    XM_ERR_A20    0x82    /* A20 error occurred */
  215. #define    XM_NO_HMA    0x90    /* HMA does not exist */
  216. #define    XM_HMA_USED    0x91    /* HMA already in use */
  217. #define    XM_NO_HMA_ALLOC    0x93    /* HMA was not allocated */
  218. #define    XM_A20_ENABLED    0x94    /* A20 line still enabled */
  219. #define    XM_NO_MEM    0xA0    /* all extended memory is allocated */
  220. #define    XM_NO_HANDLES    0xA1    /* all extended memory handles are in use */
  221. #define    XM_BAD_HANDLE    0xA2    /* handle is invalid */
  222. #define    XM_BAD_SRC    0xA3    /* invalid source handle */
  223. #define    XM_BAD_SRC_OFS    0xA4    /* invalid source offset */
  224. #define    XM_BAD_DEST    0xA5    /* invalid destination handle */
  225. #define    XM_BAD_DEST_OFS    0xA6    /* invalid destination offset */
  226. #define    XM_BAD_LENGTH    0xA7    /* length is invalid */
  227. #define    XM_BAD_OVERLAP    0xA8    /* move has invalid overlap */
  228. #define    XM_PARITY_ERROR    0xA9    /* parity error occurred */
  229. #define    XM_NOT_LOCKED    0xAA    /* block is not locked */
  230. #define    XM_LOCKED    0xAB    /* block is locked */
  231. #define    XM_LOCK_COUNT    0xAC    /* block's lock count overflowed */
  232. #define    XM_LOCK_FAILED    0xAD    /* lock failed */
  233. #define    XM_SMALLER_UMB    0xB0    /* a smaller UMB is available */
  234. #define    XM_NO_UMBS    0xB1    /* no UMBs are available */
  235. #define    XM_UMB_INVALID    0xB2    /* UMB segment number is invalid */
  236.  
  237. /*
  238.  *    The functions below are the low level driver functions, these
  239.  *    all translate to one or more INT 2FH or XMS Driver calls.  No
  240.  *    cacheing is performed by these routines, however the _xms_write
  241.  *    and _xms_realloc routines may invalidate the cache.
  242.  */
  243.  
  244. extern int        _xms_installed(void);
  245. extern _XMS_DRIVER    _xms_driver(void);
  246. extern int        _xms_version(struct _XMS_VERSION * vers);
  247. extern int        _xms_memavail(struct _XMS_FREE * mem);
  248. extern _XMS_HANDLE    _xms_alloc(_XMS_SIZE_T size);
  249. extern _XMS_HANDLE    _xms_alloc_bytes(unsigned long size);
  250. extern int        _xms_dispose(_XMS_HANDLE handle);
  251. extern int        _xms_move(struct _XMS_MOVE * move);
  252. extern unsigned long    _xms_lock(_XMS_HANDLE handle);
  253. extern int        _xms_unlock(_XMS_HANDLE handle);
  254. extern int        _xms_info(_XMS_HANDLE handle, struct _XMS_INFO * info);
  255. extern _XMS_HANDLE    _xms_resize(_XMS_HANDLE handle, _XMS_SIZE_T size);
  256. extern _XMS_HANDLE    _xms_resize_bytes(_XMS_HANDLE handle, unsigned long size);
  257.  
  258. /*
  259.  *    The next group of functions implement a higher level interface
  260.  *    to XMS which performs cacheing of memory reads and writes.  These
  261.  *    routines also hide many of the "dirty" aspects of XMS such as the
  262.  *    inability of most drivers to perform odd length transfers.
  263.  */
  264.  
  265. extern void        _xms_flush(_XMS_HANDLE handle);
  266. extern int        _xms_write(_XMS_HANDLE dst, unsigned int size,
  267.                 unsigned long ofs, far void * src);
  268. extern int        _xms_read(_XMS_HANDLE src, unsigned int size,
  269.                 unsigned long ofs, far void * dst);
  270. extern _XMS_HANDLE    _xms_zalloc(unsigned int n_elem, unsigned int size);
  271. extern int        _xms_memset(_XMS_HANDLE dst, unsigned long ofs,
  272.                 int ch, unsigned long size);
  273. extern int        _xms_memmove(_XMS_HANDLE dst, unsigned long d_ofs,
  274.                 _XMS_HANDLE src, unsigned long s_ofs, unsigned long size);
  275.  
  276. /*
  277.  *    The final group of functions implement the highest level XMS support.
  278.  *    These routines are XMS equivalents of the standard C <stdlib.h> memory
  279.  *    allocation functions, as follows:
  280.  *
  281.  *    XMS function        <stdlib.h> equivalent
  282.  *    ---------------------------------------------
  283.  *    _xms_sbrk()        sbrk()            
  284.  *    _xms_malloc()        malloc()
  285.  *    _xms_free()        free()
  286.  *    _xms_realloc()        realloc()
  287.  *    _xms_calloc()        calloc()
  288.  *
  289.  *    These routines allocate and manage memory within larger XMS blocks.
  290.  *    If possible, all allocated memory will reside in a single XMS block
  291.  *    which will be resized as necessary.  These routines should be used
  292.  *    in preference to the "low level" routines defined earlier because
  293.  *    XMS handles are a scarce resource.
  294.  *
  295.  *    All blocks handled by these routines are described by the _XMS_POINTER
  296.  *    type, which is defined as follows:
  297.  */
  298.  
  299. typedef struct {
  300.     _XMS_HANDLE    handle;        /* handle of XMS block */
  301.     unsigned long    offset;        /* offset of XMS block */
  302. }    _XMS_POINTER;
  303.  
  304. /*
  305.  *    The "handle" and "offset" fields of an _XMS_POINTER may be passed
  306.  *    to the XMS cache routines above, or even copied to an _XMS_MOVE
  307.  *    block for a low level XMS move.  For example:
  308.  *
  309.  *    _XMS_POINTER    ptr;
  310.  *    char        string[128];
  311.  *    int        len;
  312.  *
  313.  *    len = strlen(string);
  314.  *    if (_xms_malloc(len, &ptr))
  315.  *        _xms_write(ptr.handle, len + 1, ptr.offset, string);
  316.  *
  317.  *    The _xms_get() and _xms_put() routines provide an interface to
  318.  *    _xms_read() and _xms_write() which handles _XMS_POINTERS directly.
  319.  *
  320.  *    The XMS memory allocation routines below all take a pointer to
  321.  *    an _XMS_POINTER block which will be modified as necessary.  Reference
  322.  *    passing of _XMS_POINTER structures is used due to the poor efficiency
  323.  *    of structure passing with some C implementations.  For all functions,
  324.  *    the address of an _XMS_POINTER is passed as the last argument.  All of
  325.  *    these functions return an int which will be 1 on success, 0 on failure.
  326.  *    "_xms_errno" will also be conditioned.
  327.  *
  328.  *    The XMS routines will remember the size of each XMS block, down to the
  329.  *    granularity of the allocation schemes.  It is the responsibility of the
  330.  *    application code to remember the exact size of XMS objects and to avoid
  331.  *    overwriting the bounds of XMS blocks.
  332.  */
  333.  
  334. extern int    _xms_sbrk(unsigned long size, _XMS_POINTER * ptr);
  335. extern int    _xms_malloc(unsigned long size, _XMS_POINTER * ptr);
  336. extern int    _xms_free(_XMS_POINTER * ptr);
  337. extern int    _xms_realloc(unsigned long size, _XMS_POINTER * ptr);
  338. extern int    _xms_calloc(unsigned int n_elem, unsigned int size, _XMS_POINTER * ptr);
  339. extern int    _xms_get(void * dst, unsigned int size, _XMS_POINTER * src);
  340. extern int    _xms_put(void * src, unsigned int size, _XMS_POINTER * dst);
  341.  
  342. /*
  343.  *    The macros below provide a mechanism for declaring and manipulating
  344.  *    objects which may reside in either XMS or conventional memory without
  345.  *    knowing which memory type is being used by the pointer.  These macros
  346.  *    are as follows:
  347.  *    
  348.  *    XMEMPTR:    may be used to declare a union which consists of an
  349.  *            _XMS_POINTER and a conventional pointer to a specified
  350.  *            type.  The name of the new type, and the type of the
  351.  *            conventional memory pointer are passed as parameters.
  352.  *
  353.  *    XMEMALLOC:    is used to allocate storage for a pointer declared using
  354.  *            XMEMPTR.  sizeof(ptrtype) bytes of XMS or conventional
  355.  *            memory will be allocated and assigned to either the "xms"
  356.  *            or "mem.ptr" field of the union.  XMS is allocated first,
  357.  *            then conventional memory if _xms_malloc() fails.
  358.  *
  359.  *    XMEMFREE:    is used to free storage associated with a pointer declared
  360.  *            using XMEMPTR.  Either _xms_free() or free() will be used
  361.  *            to deallocate the memory associated with the pointer.
  362.  *
  363.  *    XMEMPUT:    is used to write to the memory associated with a pointer
  364.  *            declared using XMEMPTR.  Either memcpy() or _xms_put() will
  365.  *            be used to write to the memory owned by the pointer.
  366.  *
  367.  *    XMEMGET:    is used to read from the memory associated with a pointer
  368.  *            declared using XMEMPTR.  Either memcpy() or _xms_get() will
  369.  *            be used to read from the memory owned by the pointer.
  370.  *
  371.  *    XNULL:        may be used in an expression to test whether an XMEMPTR is
  372.  *            NULL. e.g. if (XNULL(ptr))
  373.  */
  374.  
  375. #define    XMEMPTR(ptrtype)    union { \
  376.     _XMS_POINTER    xms; \
  377.     struct { \
  378.         _XMS_HANDLE    handle; \
  379.         ptrtype *    ptr; \
  380.     } mem; \
  381. }
  382.  
  383. typedef XMEMPTR(void)    XVOIDPTR;    /* XMS void pointer type */
  384.  
  385. #define    XMEMALLOC(size, p)    __xmemalloc__(size, (XVOIDPTR *) &(p))
  386. #define    XMEMFREE(p)        __xmemfree__((XVOIDPTR *) &(p))
  387. #define    XMEMPUT(src, size, p)    __xmemput__(src, size, (XVOIDPTR *) &(p))
  388. #define    XMEMGET(dst, size, p)    __xmemget__(dst, size, (XVOIDPTR *) &(p))
  389. #define    XNULL(p)        (!(p).xms.handle && !(p).mem.ptr)
  390.  
  391. /*
  392.  *    Glue functions used by XMEMALLOC, XMEMFREE, XMEMPUT and XMEMGET
  393.  */
  394.  
  395. extern int    __xmemalloc__(unsigned int size, XVOIDPTR * xptr);
  396. extern int    __xmemfree__(XVOIDPTR * xptr);
  397. extern int    __xmemput__(void * src, unsigned int size, XVOIDPTR * xptr);
  398. extern int    __xmemget__(void * dst, unsigned int size, XVOIDPTR * xptr);
  399.  
  400. /*
  401.  *    The union declared by XMEMPTR may be used to either declare
  402.  *    a variable, or as part of a typedef, for example:
  403.  *
  404.  *    static XMEMPTR(char)    cptr;
  405.  *
  406.  *    declares a union called "cptr" which consists of an XMS pointer
  407.  *    and a conventional memory pointer to char.  When used within a
  408.  *    typedef, such as:
  409.  *
  410.  *    typedef XMEMPTR(int)    intptr;
  411.  *
  412.  *    the line containing the macro will expand as follows:
  413.  *
  414.  *    typedef union {
  415.  *        _XMS_POINTER    xms;
  416.  *        struct {
  417.  *            _XMS_HANDLE    handle;
  418.  *            int *        ptr;
  419.  *        } mem;
  420.  *    } intptr;
  421.  *
  422.  *    resulting in a declaration of a type "intptr" which can then be
  423.  *    used with other variable declarations, for example:
  424.  *
  425.  *    static intptr    ip;
  426.  *
  427.  *    The "mem.handle" or "xms.handle" field can be used to determine
  428.  *    whether XMS or conventional memory is being used, for example:
  429.  *
  430.  *    int    i, j;
  431.  *
  432.  *    XMEMALLOC(sizeof(int), ip);
  433.  *    if (XNULL(ip))
  434.  *        printf("XMEMALLOC failed!\n");
  435.  *    else {
  436.  *        i = 1;
  437.  *        XMEMPUT(&i, sizeof(i), ip);
  438.  *        XMEMGET(&jm sizoef(j), ip);
  439.  *        printf("j = %d\n", j);
  440.  *        XMEMFREE(ip);
  441.  *    }
  442.  */
  443.  
  444. #endif
  445.  
  446. /* 
  447.  *    End of file: "$Id: xms.h,v 1.15 94/08/12 11:31:24 colin Exp $"
  448.  */
  449.